/**
 * Copyright(c) Live2D Inc. All rights reserved.
 *
 * Use of this source code is governed by the Live2D Open Software license
 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
 */

#pragma once

#include "ACubismMotion.hpp"
#include "CubismMotionQueueManager.hpp"
#include "Model/CubismModel.hpp"

namespace Live2D
{
    namespace Cubism
    {
        namespace Framework
        {

            /**
             * @brief モーションの管理
             *
             * モーションの管理を行うクラス。
             */
            class CubismMotionManager : public CubismMotionQueueManager
            {
              public:
                /**
                 * @brief コンストラクタ
                 *
                 * コンストラクタ。
                 */
                CubismMotionManager();

                /**
                 * @brief デストラクタ
                 *
                 * デストラクタ。
                 */
                virtual ~CubismMotionManager();

                /**
                 * @brief 再生中のモーションの優先度の取得
                 *
                 * 再生中のモーションの優先度の取得する。
                 *
                 * @return  モーションの優先度
                 */
                int GetCurrentPriority() const;

                /**
                 * @brief 予約中のモーションの優先度の取得
                 *
                 * 予約中のモーションの優先度を取得する。
                 *
                 * @return  モーションの優先度
                 */
                int GetReservePriority() const;

                /**
                 * @brief 予約中のモーションの優先度の設定
                 *
                 * 予約中のモーションの優先度を設定する。
                 *
                 * @param[in]   val     優先度
                 */
                void SetReservePriority(int val);

                /**
                 * @brief 優先度を設定してモーションの開始
                 *
                 * 優先度を設定してモーションを開始する。
                 *
                 * @param[in]   motion          モーション
                 * @param[in]   autoDelete      再生が狩猟したモーションのインスタンスを削除するならtrue
                 * @param[in]   priority        優先度
                 * @return
                 * 開始したモーションの識別番号を返す。個別のモーションが終了したか否かを判定するIsFinished()の引数で使用する。開始できない時は「-1」
                 */
                CubismMotionQueueEntryHandle StartMotionPriority(ACubismMotion *motion, bool autoDelete, int priority);

                /**
                 * @brief モーションの更新
                 *
                 * モーションを更新して、モデルにパラメータ値を反映する。
                 *
                 * @param[in]   model   対象のモデル
                 * @param[in]   deltaTimeSeconds    デルタ時間[秒]
                 * @retval  true    更新されている
                 * @retval  false   更新されていない
                 */
                bool UpdateMotion(CubismModel *model, csmFloat32 deltaTimeSeconds);

                /**
                 * @brief モーションの予約
                 *
                 * モーションを予約する。
                 *
                 * @param[in]   priority    優先度
                 * @retval  true    予約できた
                 * @retval  false   予約できなかった
                 */
                bool ReserveMotion(int priority);

              private:
                int _currentPriority; ///<  現在再生中のモーションの優先度
                int
                    _reservePriority; ///<  再生予定のモーションの優先度。再生中は0になる。モーションファイルを別スレッドで読み込むときの機能。
            };

        } // namespace Framework
    }     // namespace Cubism
} // namespace Live2D
